﻿using System.Linq.Expressions;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Query;

namespace ZeroSum.Extend.EFCore.MySql.EntityFrameworks;

public static class EntityTypeBuilderQueryFilterExtensions
{
    /// <summary>
    ///     Support multiple HasQueryFilter calls on same entity type
    ///     https://github.com/dotnet/efcore/issues/10275
    /// </summary>
    internal static void AddQueryFilter<T>(this EntityTypeBuilder entityTypeBuilder,
        Expression<Func<T, bool>> expression)
    {
        var parameterType = Expression.Parameter(entityTypeBuilder.Metadata.ClrType);
        var expressionFilter =
            ReplacingExpressionVisitor.Replace(expression.Parameters.Single(), parameterType, expression.Body);

        var currentQueryFilter = entityTypeBuilder.Metadata.GetQueryFilter();
        if (currentQueryFilter is not null)
        {
            var currentExpressionFilter = ReplacingExpressionVisitor.Replace(currentQueryFilter.Parameters.Single(),
                parameterType, currentQueryFilter.Body);
            expressionFilter = Expression.AndAlso(currentExpressionFilter, expressionFilter);
        }

        var lambdaExpression = Expression.Lambda(expressionFilter, parameterType);
        entityTypeBuilder.HasQueryFilter(lambdaExpression);
    }
}